package com.ckk.eurekaclient.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ckk.eurekaclient.constants.MqQueue;
import com.ckk.eurekaclient.enums.SyncTypeEnum;
import com.ckk.eurekaclient.mapper.MarkEditionMapper;
import com.ckk.eurekaclient.mapper.MarkMapper;
import com.ckk.eurekaclient.mapper.MarkerMapper;
import com.ckk.eurekaclient.pojo.Admin;
import com.ckk.eurekaclient.pojo.MarkEditionPo;
import com.ckk.eurekaclient.pojo.MarkPo;
import com.ckk.eurekaclient.pojo.MarkerPo;
import com.ckk.eurekaclient.service.IMarkerService;
import com.ckk.eurekaclient.service.mq.MqSendService;
import com.ckk.eurekaclient.vo.mq.MarkMqInsertVo;
import com.ckk.eurekaclient.vo.req.MarkerReqVo;
import com.ckk.eurekaclient.vo.req.QueryMarkEditionReqVo;
import com.ckk.eurekaclient.vo.resp.MarkFinalRespVo;
import com.ckk.eurekaclient.vo.resp.MarkRespVo;
import com.ckk.eurekaclient.vo.resp.MarkeditonRespVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;


/**
 * 
 * @author zhujunjun
 * @date 2021/05/20 09:28
 **/
@Service
public class MarkerServiceImpl extends ServiceImpl<MarkerMapper, MarkerPo> implements IMarkerService {

    @Autowired
    private MarkEditionMapper markEditionMapper;

    @Autowired
    private MarkerMapper markerMapper;

    @Autowired
    private MarkMapper markMapper;

    @Autowired
    private MqSendService mqSendService;

    @Override
    public List<MarkEditionPo> queryMarkEdition(QueryMarkEditionReqVo reqVo) {
        String sql = "select guid from mark where layer = " + reqVo.getLayer() + " and id = " + reqVo.getId();
        List<MarkEditionPo> markEditionPoList = markEditionMapper.selectList(new LambdaQueryWrapper<MarkEditionPo>()
                .inSql(MarkEditionPo::getMarkGuid, sql));
        //返回当前打点人员对该点的打点历史。
        return markEditionPoList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String addMarker(String layer, String xy) {
        Integer intLayer = Integer.parseInt(layer);
        //获取token中缓存的值
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        //查询标记表中是否存在该layer的值，并且找到id值最大的那条数据
        MarkPo markPo0 = markMapper.selectOne(new LambdaQueryWrapper<MarkPo>()
                .eq(MarkPo::getLayer, intLayer)
                .orderByDesc(MarkPo::getId).last("limit 0,1"));
        MarkPo markPo = new MarkPo();
        markPo.setLayer(intLayer);
        markPo.setEdition(1);
        MarkEditionPo markEditionPo0 = new MarkEditionPo();
        if (markPo0 == null) {
            //默认为1
            markPo.setId(1);
            markMapper.insert(markPo);
        } else {
            //最大值+1
            markPo.setId(markPo0.getId() + 1);
            markMapper.insert(markPo);
            markEditionPo0 = markEditionMapper.selectOne(new LambdaQueryWrapper<MarkEditionPo>()
                    .eq(MarkEditionPo::getMarkGuid, markPo0.getGuid())
                    .eq(MarkEditionPo::getEdition, markPo0.getEdition()));
            Assert.notNull(markEditionPo0, layer + ":数据错误，请联系后台处理数据！");
        }
        markEditionPo0.setXy(xy);
        markEditionPo0.setMarkGuid(markPo.getGuid());
        markEditionPo0.setEdition(1);
        markEditionPo0.setAdminId(((Admin)authentication.getPrincipal()).getId());
        markEditionPo0.setMarkPic(layer + "_" + markPo.getId() + "_" + 1);
        markEditionMapper.insert(markEditionPo0);
        MarkMqInsertVo markMqInsertVo = new MarkMqInsertVo();
        markMqInsertVo.setMarkPo(markPo);
        markMqInsertVo.setMarkEditionPo(markEditionPo0);
        mqSendService.send(MqQueue.EXCHANGE_BEHIND_FRONT, SyncTypeEnum.INSERT.getCode(), markMqInsertVo);
        return layer + "_" + markPo.getId() + "_" + 1;
    }

    @Override
    public void deleteMarker(String guid) {
        markMapper.delete(new LambdaQueryWrapper<MarkPo>().eq(MarkPo::getGuid, guid));
        markEditionMapper.delete(new LambdaQueryWrapper<MarkEditionPo>()
                .eq(MarkEditionPo::getMarkGuid, guid));
        mqSendService.send(MqQueue.EXCHANGE_BEHIND_FRONT, SyncTypeEnum.DELETE.getCode(), guid);
    }

    @Override
    public void updateMarker(MarkerReqVo reqVo) {
        //获取token中缓存的值
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        MarkEditionPo markEditionPo = markEditionMapper.selectOne(new LambdaQueryWrapper<MarkEditionPo>()
                .eq(MarkEditionPo::getMarkGuid, reqVo.getGuid())
                .orderByDesc(MarkEditionPo::getEdition)
                .last("limit 1"));
        BeanUtils.copyProperties(reqVo, markEditionPo);
        markEditionPo.setEdition(markEditionPo.getEdition() + 1);
        markEditionPo.setAdminId(((Admin)authentication.getPrincipal()).getId());
        if (reqVo.getPic()) {
            String[] pic = markEditionPo.getMarkPic().split("_");
            markEditionPo.setMarkPic(pic[0] + "_" + pic[1] + "_" + markEditionPo.getEdition());
        }
        markEditionMapper.insert(markEditionPo);
        MarkPo mark = new MarkPo();
        mark.setGuid(reqVo.getGuid());
        mark.setEdition(markEditionPo.getEdition());
        markMapper.updateById(mark);
        MarkMqInsertVo markMqInsertVo = new MarkMqInsertVo();
        markMqInsertVo.setMarkPo(mark);
        markMqInsertVo.setMarkEditionPo(markEditionPo);
        mqSendService.send(MqQueue.EXCHANGE_BEHIND_FRONT, SyncTypeEnum.UPDATE.getCode(), markMqInsertVo);
    }

    @Override
    public List<MarkFinalRespVo> getMark() {
        List<MarkRespVo> markRespVoList = markMapper.getMark();
        return getMarkFinal(markRespVoList);
    }

    @Override
    public List<MarkFinalRespVo> getMarkByLayer(String id) {
        List<MarkRespVo> markRespVoList = markMapper.getMarkByLayer(id);
        return getMarkFinal(markRespVoList);
    }

    /**
     * 处理标记点数据的公共方法
     * @param markRespVoList
     * @return
     */
    private List<MarkFinalRespVo> getMarkFinal(List<MarkRespVo> markRespVoList) {
        List<MarkFinalRespVo> markFinalRespVoList = markRespVoList.stream().map(o -> {
            MarkFinalRespVo markFinalRespVo = new MarkFinalRespVo();
            BeanUtils.copyProperties(o, markFinalRespVo);
            markFinalRespVo.setXy(o.getXy().split(","));
            return markFinalRespVo;
        }).collect(Collectors.toList());
        return markFinalRespVoList;
    }
}
